home *** CD-ROM | disk | FTP | other *** search
/ Especial Multimedia / Especial Multimedia.iso / Multimed / Prg / PROGRESS.ZIP / PROGRESS.CPP < prev    next >
C/C++ Source or Header  |  1997-09-14  |  5KB  |  136 lines

  1. // Windows Progress Bar Control
  2.  
  3. #include <windows.h>
  4. #include "progress.h"
  5.  
  6. extern "C" {
  7.   long far pascal _export ProgressBarProc(HWND, UINT, WPARAM, LPARAM);
  8. }
  9.  
  10. /*-----------------------------------------------------------------------------
  11. This function registers the PROGRESSBAR class. It is called automatically when
  12. the program starts up.
  13.  
  14. The external variables _hPrev and _hInstance duplicate the arguments
  15. hPrevInstance and hInstance, which are passed to WinMain(). If the startup
  16. code does not supply these external variables, you must pass the arguments to
  17. this function and call it explicitly before invoking any PROGRESSBAR control.
  18. -----------------------------------------------------------------------------*/
  19.  
  20. extern HINSTANCE _hPrev, _hInstance;
  21.  
  22. static void register_progress_bar(void)
  23. {
  24.   if (!_hPrev)
  25.   {
  26.     WNDCLASS w;
  27.     w.cbClsExtra = 0;
  28.     w.cbWndExtra = 4*sizeof(WORD);
  29.     w.hbrBackground = (HBRUSH) COLOR_WINDOW + 1;
  30.     w.hCursor = LoadCursor(NULL, IDC_ARROW);
  31.     w.hIcon = NULL;
  32.     w.hInstance = _hInstance;
  33.     w.lpfnWndProc = ProgressBarProc;
  34.     w.lpszClassName = "PROGRESSBAR";
  35.     w.lpszMenuName = NULL;
  36.     w.style = 0;
  37.     RegisterClass(&w);
  38.   }
  39. }
  40.  
  41. #pragma startup register_progress_bar
  42.  
  43. /*-----------------------------------------------------------------------------
  44. This function receives all messages directed to the control.
  45. -----------------------------------------------------------------------------*/
  46.  
  47. long far pascal _export ProgressBarProc(HWND handle, UINT message,
  48.   WPARAM wParam, LPARAM lParam)
  49. {
  50.   WORD height = GetWindowWord(handle, 0);
  51.   WORD width = GetWindowWord(handle, 2);
  52.   WORD completed = GetWindowWord(handle, 4);
  53.   WORD total = GetWindowWord(handle, 6);
  54.   switch (message)
  55.   {
  56.     case WM_CREATE:
  57.     {
  58.       SetWindowWord(handle, 0, ((CREATESTRUCT far *) lParam)->cy);  // height
  59.       SetWindowWord(handle, 2, ((CREATESTRUCT far *) lParam)->cx);  // width
  60.       SetWindowWord(handle, 6, 100); // default value of total
  61.       return 0;
  62.     }
  63.     case WM_PAINT:
  64.     {
  65.       PAINTSTRUCT paint;
  66.       HDC dc = BeginPaint(handle, &paint);
  67.       HPEN pen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_WINDOWTEXT));
  68.       HPEN old_pen = SelectObject(dc, pen);
  69.       HBRUSH brush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  70.       HBRUSH old_brush = SelectObject(dc, brush);
  71.       RECT r;
  72.       char text[5];
  73.       // draw border
  74.       Rectangle(dc, 0, 0, width-1, height-1);
  75.       // display completion percentage
  76.       SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
  77.       SetBkColor(dc, GetSysColor(COLOR_WINDOW));
  78.       r.left = r.top = 1;
  79.       r.bottom = height - 2;
  80.       r.right = width - 2;
  81.       wsprintf(text, "%d%%", (100L * (DWORD) completed) / (DWORD) total);
  82.       DrawText(dc, text, lstrlen(text), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  83.       // invert progress portion
  84.       r.right = 1 + ((DWORD) (width - 3) * (DWORD) completed) / (DWORD) total;
  85.       if (r.right > r.left)
  86.         InvertRect(dc, &r);
  87.       SelectObject(dc, old_pen);
  88.       DeleteObject(pen);
  89.       SelectObject(dc, old_brush);
  90.       DeleteObject(brush);
  91.       EndPaint(handle, &paint);
  92.       return 0;
  93.     }
  94.     case PB_SETCOMPLETED:
  95.     {
  96.       RECT r;
  97.       r.top = 1;
  98.       r.bottom = height - 2;
  99.       SetWindowWord(handle, 4, wParam); // completed
  100.       if ((100L * (DWORD) wParam) / (DWORD) total != (100L * (DWORD) completed) / (DWORD) total)
  101.       {
  102.         HDC dc = GetDC(handle);
  103.         unsigned text_width = (WORD) GetTextExtent(dc, "100%", 4);
  104.         r.left = 1 + (width - 2) / 2 - (text_width + 1) / 2;
  105.         r.right = 1 + (width - 2) / 2 + (text_width + 1) / 2;
  106.         InvalidateRect(handle, &r, TRUE);
  107.         ReleaseDC(handle, dc);
  108.       }
  109.       r.left = 1 + ((DWORD) (width - 3) * (DWORD) completed) / (DWORD) total;
  110.       r.right = 1 + ((DWORD) (width - 3) * (DWORD) wParam) / (DWORD) total;
  111.       if (r.left != r.right)
  112.       {
  113.         if (r.left > r.right)
  114.         {
  115.           int x = r.left;
  116.           r.left = r.right;
  117.           r.right = x;
  118.         }
  119.         InvalidateRect(handle, &r, TRUE);
  120.       }
  121.       return 0;
  122.     }
  123.     case PB_GETCOMPLETED:
  124.       return completed;
  125.     case PB_SETTOTAL:
  126.       SetWindowWord(handle, 6, wParam); // total
  127.       SetWindowWord(handle, 4, 0); // completed
  128.       InvalidateRect(handle, NULL, TRUE);
  129.       return 0;
  130.     case PB_GETTOTAL:
  131.       return total;
  132.   }
  133.   return DefWindowProc(handle, message, wParam, lParam);
  134. }
  135.  
  136.